import {
  chunkArray,
  sendMessage,
  executeSequentially,
  awaitDelayTime,
  calculateMaxInputAmountOptimized,
  sleep,
} from "../../utils";
import type { TManualVerifyGoods } from "../../type";
import CurrencyConverter from "../../currencyConverter";
import { deleteSkc, parsePrice, findDeleteButton } from "./utils";

const converter = new CurrencyConverter();

function getNextElement() {
  const nextElement = document.querySelector<HTMLElement>(
    ".ant-pagination-next"
  );
  return nextElement;
}

function checkHasNextPage() {
  const nextElement = getNextElement();
  if (!nextElement) {
    return false;
  }
  return !nextElement.className.includes("ant-pagination-disabled");
}

function doNextPage() {
  const nextElement = getNextElement();
  if (nextElement) {
    nextElement.click();
  }
}

function getTableRowDateRowKey() {
  const tableBody = document.querySelector(".ant-table-tbody");
  if (!tableBody) {
    return "";
  }

  const firstRow = tableBody.querySelector(".ant-table-row");
  if (!firstRow) {
    return "";
  }

  const currentKey = firstRow.getAttribute("data-row-key");
  return currentKey || "";
}
function scrollToTr(tr: HTMLElement) {
  const tbody = tr.closest(".ant-table-body");
  if (!tbody) return;
  const trRect = tr.getBoundingClientRect();
  const tbodyRect = tbody.getBoundingClientRect();
  const isVisible =
    trRect.top >= tbodyRect.top && trRect.bottom <= tbodyRect.bottom;

  if (isVisible) return;
  const trTop = tr.offsetTop;
  tbody.scrollTop = trTop;
}

function checkFirstRowKey(targetKey: string) {
  return new Promise((resolve, reject) => {
    let checkTimer: number;
    const timeoutId = setTimeout(() => {
      clearTimeout(checkTimer);
      reject("超过10秒还没翻页成功");
    }, 10000);

    const checkRow = () => {
      const currentKey = getTableRowDateRowKey();
      if (!currentKey) {
        checkTimer = setTimeout(checkRow, 1000);
        return;
      }

      if (currentKey !== targetKey) {
        clearTimeout(timeoutId);
        resolve(currentKey);
      } else {
        checkTimer = setTimeout(checkRow, 1000);
      }
    };
    checkRow();
  });
}

function getSkuCodeByElement(row: Element) {
  let skuCode = "";
  const skuCodeElement = row.querySelector('[class*="index__sku-info-code--"]');
  if (skuCodeElement) {
    const match = skuCodeElement.textContent?.match(/SKU:\s([a-zA-Z0-9]+)/);

    if (match) {
      skuCode = match[1];
    }
  }
  return skuCode;
}

async function setReactInputValueBySheinShop(
  tableRowDateRowKey: string,
  value: number,
  finallyRate: number
): Promise<boolean> {
  return new Promise((resolve) => {
    chrome.runtime.sendMessage(
      {
        type: "setReactInputValueBySheinShop",
        tableRowDateRowKey,
        value,
        finallyRate,
      },
      (response) => {
        resolve(response?.success || false);
      }
    );
  });
}

function findPreviousDeleteButton(trElement: Element) {
  // 如果自己有直接返回
  const currentRowFixedRightCell = trElement.querySelector(
    ".ant-table-cell-fix-right-first"
  );

  if (currentRowFixedRightCell) {
    const deleteButton = findDeleteButton(currentRowFixedRightCell);
    if (deleteButton) return deleteButton;
  }

  // 获取当前tr的前一个兄弟元素
  let previousTr = trElement.previousElementSibling;
  // 循环查找前一个兄弟元素
  while (previousTr) {
    const fixedRightCell = previousTr.querySelector(
      ".ant-table-cell-fix-right-first"
    );

    if (fixedRightCell) {
      const deleteButton = findDeleteButton(fixedRightCell);
      if (deleteButton) return deleteButton;
    }

    previousTr = previousTr.previousElementSibling;
  }

  return false;
}

function extractRange(text: string) {
  const pattern = /(\d+(?:\.\d+)?)%\s*~\s*(\d+(?:\.\d+)?)%/;
  const match = text.match(pattern);

  if (!match) {
    return null;
  }

  const min = parseFloat(match[1]);
  const max = parseFloat(match[2]);

  return {
    min: min / 100,
    max: max / 100,
  };
}

async function formatSkuListToSkuInfoMap({
  skuInfoMap,
  platform,
  shopId,
  multiplierMinInput,
  multiplierMaxInput,
  operateMap = {},
}: {
  skuInfoMap: any;
  platform: string;
  shopId: string;
  multiplierMinInput: number;
  multiplierMaxInput: number;
  operateMap: any;
}): Promise<void> {
  const storage = await chrome.storage.sync.get(["baoyiplus_accessToken"]);
  const { baoyiplus_accessToken = "" } = storage;
  if (baoyiplus_accessToken) {
    const skuInfoRowList = document.querySelectorAll(
      ".ant-table-body .ant-table-row"
    );
    const skuInfoRowMap: any = {};
    const skuCodeList: any[] = [];
    for (let i = 0; i < Array.from(skuInfoRowList).length; i++) {
      const row = skuInfoRowList[i];
      const discountCardElement = row.querySelectorAll(
        "[class*='index__discountCard--'"
      );
      let __hasDiscountCard = false;
      if (discountCardElement && discountCardElement.length) {
        const discountCardElementItem = Array.from(discountCardElement).find(
          (discountCard) => {
            const title = discountCard.querySelector(
              "[class*='index__title--'"
            );
            return title?.textContent?.includes("VIP");
          }
        );
        if (discountCardElementItem) {
          __hasDiscountCard = true;
          const inputRadio = discountCardElementItem.querySelector(
            '.ant-radio-input[type="radio"]'
          ) as HTMLInputElement | null;
          const checked = inputRadio ? inputRadio.checked : false;
          if (!checked) {
            (discountCardElementItem as HTMLElement).click();
          }
        }
      }

      const skuCode = getSkuCodeByElement(row);

      const cells = Array.from(row.children).filter(
        (child) =>
          child.classList.length === 1 &&
          child.classList.contains("ant-table-cell")
      );

      const length = cells.length;

      let rateRange = null;
      const priceExtraItems = row.querySelectorAll(
        '[class*="index__price-extra-item--"]'
      );

      for (let i = 0; i < priceExtraItems.length; i++) {
        const priceExtraItemCell = priceExtraItems[i];
        const extractRangeValue = extractRange(
          priceExtraItemCell?.textContent || ""
        );

        if (extractRangeValue) {
          rateRange = extractRangeValue;
          break;
        }
      }

      const priceTdElement = cells?.[length - 3 - (__hasDiscountCard ? 1 : 0)];

      let priceTdText = "";
      if (priceTdElement.children.length) {
        const siteItemElement = priceTdElement.querySelector(
          '[class*="index__site-item--"]'
        );
        if (siteItemElement && siteItemElement.firstElementChild) {
          priceTdText = siteItemElement.firstElementChild.textContent || "";
        }
      } else {
        priceTdText = priceTdElement?.textContent || "";
      }
      const { price, currency } = parsePrice(priceTdText);

      const currentSkuDelete = findPreviousDeleteButton(row);

      const tableRowDateRowKey = row.getAttribute("data-row-key");
      if (
        !(skuCode in operateMap) &&
        skuCode &&
        rateRange &&
        currentSkuDelete &&
        price &&
        currency
      ) {
        operateMap[skuCode] = true;
        skuCodeList.push(skuCode);
        skuInfoRowMap[skuCode] = {
          skuCode,
          rateRange,
          currentSkuDelete,
          price,
          currency,
          tableRowDateRowKey,
          trElement: row,
          __hasDiscountCard,
        };
      }
    }
    let currentPageUseDelete = false;

    if (!skuCodeList.length) {
      return Promise.resolve();
    }

    const chunkSkuCodeList = chunkArray(skuCodeList, 50);

    const promiseArray: any[] = [];
    chunkSkuCodeList.forEach((skuCodeChunk) => {
      promiseArray.push(
        sendMessage({
          type: "getSkuPrice",
          data: {
            outId: `#in#${skuCodeChunk.join(",")}`,
            shopId,
          },
          platform,
          token: baoyiplus_accessToken,
        })
      );
    });

    return Promise.all(promiseArray).then((resList: any) => {
      const executeSequentiallyArray: any[] = [];
      const erpCodeInfoMap = resList.reduce((obj: any, res: any) => {
        (res?.data || []).forEach((record: any) => {
          const { outId, sourcePrice, sourceCurrency } = record;
          if (outId in skuInfoRowMap) {
            obj[outId] = {
              sourcePrice,
              sourceCurrency,
            };
          }
        });
        return obj;
      }, {});

      Object.keys(skuInfoRowMap).forEach((outId) => {
        const {
          currency,
          price,
          rateRange,
          tableRowDateRowKey,
          currentSkuDelete,
          trElement,
          __hasDiscountCard,
        } = skuInfoRowMap[outId];
        if (outId in erpCodeInfoMap) {
          const { sourcePrice, sourceCurrency } = erpCodeInfoMap[outId];
          executeSequentiallyArray.push(async () => {
            const editInputPrice = await converter.convert(
              sourcePrice,
              sourceCurrency,
              currency
            );
            const numberPrice = Number(price);
            const finallyPrice = calculateMaxInputAmountOptimized({
              currencyPrice: numberPrice,
              reduceRateRange: rateRange,
              multiplierMinInput,
              multiplierMaxInput,
              purchasePrice: editInputPrice,
            });
            if (finallyPrice) {
              scrollToTr(trElement);
              const finallyRate = Math.round(
                ((numberPrice - finallyPrice) / numberPrice) * 100
              );
              // await sleep(500);
              return setReactInputValueBySheinShop(
                tableRowDateRowKey,
                finallyPrice,
                __hasDiscountCard ? finallyRate : 0
              );
            } else {
              if (!document.contains(currentSkuDelete)) {
                return Promise.resolve(true);
              }
              scrollToTr(trElement);
              currentPageUseDelete = true;
              return deleteSkc(currentSkuDelete);
            }
          });
        } else {
          executeSequentiallyArray.push(() => {
            if (!document.contains(currentSkuDelete)) {
              return Promise.resolve(true);
            }
            scrollToTr(trElement);
            currentPageUseDelete = true;
            return deleteSkc(currentSkuDelete);
          });
        }
      });

      return executeSequentially(executeSequentiallyArray).then(() => {
        if (currentPageUseDelete) {
          return formatSkuListToSkuInfoMap({
            skuInfoMap,
            platform,
            shopId,
            multiplierMinInput,
            multiplierMaxInput,
            operateMap,
          });
        }
        return Promise.resolve();
      });
    });
  } else {
    alert("登录已经过期，请先点击右上角重新登录");
    return Promise.reject("登录已经过期，请先点击右上角重新登录");
  }
}

async function manualVerifyPageGoods({
  multiplierMinInput = 1,
  multiplierMaxInput = 1,
  action,
  skuInfoMap,
  platform,
  shopId,
}: TManualVerifyGoods): Promise<{ action: string }> {
  try {
    await formatSkuListToSkuInfoMap({
      skuInfoMap,
      platform,
      shopId,
      multiplierMinInput,
      multiplierMaxInput,
      operateMap: {},
    });
    await awaitDelayTime();
    const currentKey = getTableRowDateRowKey();
    const hasNextPage = checkHasNextPage();
    if (!hasNextPage) {
      return Promise.resolve({
        action: "end",
      });
    }
    doNextPage();
    await checkFirstRowKey(currentKey);
    return Promise.resolve({
      action: "next",
    });
  } catch (error) {
    return Promise.reject(error);
  }
}

export default {
  manualVerifyPageGoods,
};
